fix: RAC modal layout shift when auto-focusing input#10102
Conversation
| // Hide the modal initially, since an auto-focused input may cause a viewport resize in the next frame. | ||
| // If so, delay the reveal by another frame to avoid layout shift when the viewport settles. |
There was a problem hiding this comment.
I tried to squeeze this into the hook layer (e.g. useModalOverlay), but that was challenging, due to expectations around a single render pass. This is also pretty opinionated styling, so I ultimately decided to place it in RAC instead.
| preventScrollCount++; | ||
| if (preventScrollCount === 1) { | ||
| if (isIOS()) { | ||
| if (isIOS() && isWebKit()) { |
|
|
||
| if (!opts || !opts.preventScroll) { | ||
| scrollIntoViewWhenReady(this, wasKeyboardVisible); | ||
| Reflect.defineProperty(HTMLElement.prototype, 'focus', { |
snowystinger
left a comment
There was a problem hiding this comment.
Does Popover.tsx have the same problem? I was hopeful this would fix the S2 Combobox which scrolls the main page and focuses the input when tapping the trigger, and the Popover ends up the wrong size in iOS26, but I was unsuccessful on a quick try.
In general we don't like to delay things by any sort of timer though know that they are sometimes unavoidable. What were some other avenues you explored?
Does this work with native elements that have autofocus? or only RAC components? React autoFocus timing is different from native is why I'm asking. I suspect it works for both given that the React one is "slower".
Closes
Before vs After
Screen.Recording.2026-05-23.at.11.11.59.PM.mov
Screen.Recording.2026-05-25.at.6.32.24.PM.2.mov
✅ Pull Request Checklist:
📝 Test Instructions:
🧢 Your Project: